package com.xiaolai.iodemo.Validate.core;

import com.xiaolai.iodemo.Validate.annotaction.Validate;
import com.xiaolai.iodemo.Validate.structure.Target;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Created by Administrator on 2015/12/9.
 */
public class ValidateHandlerCaller{
    Target target;

    /**
     * @param obj 待处理类
     */
    public ValidateHandlerCaller(Object obj) {
        if (this.target == null) {
            target = this.getTarget(obj);
        }
    }


    public void validateCaller() {
        for (Map.Entry<Field, HandlerDefinition> entry : target.getTarget().entrySet()) {
            final Field field = entry.getKey();
            final HandlerDefinition hd = entry.getValue();
            Thread t=new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        ValidateHandler handler = ValidateHandlerScanner.customHandlerScanner(field,target.getObject());
                        handler.validate(field);
                    } catch (ValidateException ex) {
                        Method validateExceptionHandlerScanner = ValidateHandlerScanner.validateExceptionHandlerScanner(hd);
                        callMethod(validateExceptionHandlerScanner);
                    }
                }

                protected void callMethod(Method validateExceptionHandlerScanner) {
                    try {
                        if (validateExceptionHandlerScanner.isAccessible()) {
                            validateExceptionHandlerScanner.setAccessible(true);
                        }
                        validateExceptionHandlerScanner.invoke(this, hd);
                    } catch (IllegalAccessException ex) {
                        Logger logger = Logger.getLogger(ex.getMessage());
                        logger.setLevel(Level.WARNING);
                    } catch (InvocationTargetException ex) {
                        Logger logger = Logger.getLogger(ex.getMessage());
                        logger.setLevel(Level.WARNING);
                    } finally {
                        validateExceptionHandlerScanner.setAccessible(false);
                    }
                }
            });
        }

    }

    protected Target getTarget(Object obj) {
        Class cls = obj.getClass();
        Target target = new Target();
        for (Field field : cls.getDeclaredFields()) {
            if (field.isAccessible()) {
                field.setAccessible(true);
            }
            target.setTarget(obj, field, field.getAnnotation(Validate.class).value());
            field.setAccessible(false);

        }
        return target;

    }
}

